import { Injectable, Type } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import {
  OAuthService,
  JwksValidationHandler,
  AuthConfig,
} from 'angular-oauth2-oidc';
import { StoreService } from './store.service';
import { DataService } from './data.service';
import { Permission, User } from './app.interface';
import { isNull } from 'util';
@Injectable({
  providedIn: 'root',
})
export class AppService {
  constructor(
    private httpService: HttpClient,
    private oauthService: OAuthService,
    private storeService: StoreService,
    private dataService: DataService
  ) {
    this.httpService.get('assets/config.json').subscribe((data: any) => {
      this.fetchConfig(data);
      if (data.Authorize) {
        const conf: AuthConfig = this.getAuthConfig(
          data.authUrl,
          data.clientId
        );
        this.storeService.Authorize = data.Authorize;
        this.storeService.permissions = data.permissions;
        this.storeService.maxModel = data.maxModel;
        this.oauthService.configure(conf);
        this.oauthService.tokenValidationHandler = new JwksValidationHandler();
        this.oauthService.loadDiscoveryDocumentAndTryLogin().then(() => {
          const claims: any = this.oauthService.getIdentityClaims();

          if (claims === null) {
            this.oauthService.initImplicitFlow();
            return;
          }

          const url =
            this.storeService.conf.authUrl +
            '/Account/GetPermission/' +
            claims.idp.toString().trim();
          this.httpService.get(url).subscribe(
            (pms: Permission) => {
              console.log(pms);
              this.sysPermission = pms;
              if (!this.validPermission()) {
                //alert('没有管理权限');
              } else {
                this.storeService.claims = pms;
                this.storeService.loginUser = pms.User;
                console.log(this.storeService.loginUser);
                this.preloadData();
              }
            },
            (error) => {
              console.log(error);
            }
          );
        });
      } else {
        this.storeService.loginUser = new User();
      }
    });
  }
  sysPermission: Permission;
  public validPermission(): boolean {
    const pl = this.storeService.permissions.split(',');

    if (isNull(this.sysPermission) || pl === undefined || pl.length === 0) {
      alert('没有操作权限，请联系管理员');
      return false;
    }
    let r = false;
    pl.forEach((p) => {
      if (
        this.sysPermission.ValidRoleList.findIndex(
          (v) => v.Name.trim() === p.trim() && v.Positive
        ) > -1
      ) {
        r = r || true;
      }
    });
    if (!r) {
      alert('没有操作权限，请联系管理员');
      return false;
    }
    return true;
  }
  /**
   * 获取认证配置
   * @param authUrl 认证 url
   * @param client 客户端 id
   */
  private getAuthConfig(authUrl: string, client: string): AuthConfig {
    return {
      issuer: authUrl,
      // URL of the SPA to redirect the user to after login
      redirectUri: window.location.origin,
      // client id
      clientId: client,
      // scope
      scope: 'openid profile',
      // allow http
      requireHttps: false,
    };
  }
  /**
   * 装填配置文件
   * @param data 配置文件
   */
  public fetchConfig(data: any): void {
    this.storeService.conf.clientId = data.clientId;
    this.storeService.conf.authUrl = data.authUrl;
    this.storeService.conf.clientPassword = data.clientPassword;
    this.storeService.conf.apiUrl = data.apiUrl;

    this.storeService.conf.language = data.language;
  }
  /**
   * 预加载数据
   */
  public preloadData(): void {
    // this.dataService.getUsers(() => {});
    // this.dataService.getDepartments(() => {});
    // this.dataService.getGroups(() => {});
    // this.dataService.getModules(() => {});
    // this.dataService.getRoles(() => {});
    // this.dataService.getScopes(() => {});
  }

  public getType = function (obj) {
    if (obj == null) {
      return null;
    } else if (obj instanceof Object) {
      return obj.constructor;
    } else if (obj.tagName != null) {
      return obj.tagName;
    } else {
      return typeof obj;
    }
  };
  public getAttributes = function (obj) {
    var methods = new Array();
    for (let key in obj) {
      methods.push(new Type(obj[key], this.getType(obj[key]), key));
    }
    return methods;
  };
  public getAttributeNames = function (obj) {
    var methods = new Array();
    for (let key in obj) {
      methods.push(key);
    }
    return methods;
  };
}
